//
//  Application.swift
//  App
//
//  Created by 蒋晨成a on 2021/12/23.
//
import App_Common
import App_Common_Analysis
import App_Community
import App_Game
import App_Information
import App_Login
import App_Main
import App_Profile
import Center
import Foundation
import Service
import UICore
import UIKit

private extension Application {
    static let bootstrapperList: [Bootable.Type] = [
        Service.Bootstrapper.register(environment: ServiceEnvironment()).self,
        Center.Bootstrapper.register(environment: CenterEnvironment()).self,
        UICore.Bootstrapper.register(environment: UICoreEnvironment()).self,
        App_Common.Bootstrapper.register(environment: AppEnvironment()).self,
    ]

    static let routableList: [Routable.Type] = App_Common.routableList + App_Login.routableList + App_Profile.routableList

    static let actableList: [Actable.Type] = App_Common.actableList + App_Login.actableList
}

// 这里只暴露给 AppDelegate, 对于 Modules 不可见
// App 依赖 Modules，但 Modules 不可以依赖 App
// 若需要调用 Application 的方法，需要 Application 主动注入。或新引入一层
public extension Application {
    static func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) {
        bootstrap()
    }
}

// MARK: - Scene Delegate

public extension Application {
    static func scene(_ scene: UIScene, willConnectTo _: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) -> UIWindow? {
        guard let windowScene = (scene as? UIWindowScene) else { return nil }
        cache(connectionOptions: connectionOptions)
        append(windowScene: windowScene)
        setup()
        return window
    }
}

private extension Application {
    static func bootstrap() {
        bootstrapperList.forEach { $0.bootstrap() }
        routableList.forEach { Router.register(moduleName: $0.routePattern, description: $0.description, factory: $0.initialize) }
        actableList.forEach { Router.register(actorName: $0.routePattern, description: $0.description, action: $0.act) }
        registerBaseEvent()

        // 用户状态发生变化时，需要底层调用 App 层的 setup 方法，在这里向底层注入
        App_Login.enterAppCallback = login
        Center.enterAppCallback = login
    }

    static func setup() {
        enterMain()
    }

    static func login() {
        switch UserCenter.isLogin {
        case false:
            enterMain()
            Router.push(pattern: "login")
//            window.rootViewController = loginNavigationControllerType.init()
        case true:
            enterMain()
        }
    }

    static func enterMain() {
        window.rootViewController = tabBarViewControllerType.init(viewControllers: [
            gameNavigationControllerType.init(),
            informationNavigationControllerType.init(),
            communityNavigationControllerType.init(),
            profileNavigationControllerType.init(),
        ])
    }

    static func registerBaseEvent() {
        Base.register(
            viewWillAppearAction: {
                AppAnalysis.beginLogPageView(name: $0)
                logger.trace("\($0) viewWillAppear")
            },
            viewWillDisappearAction: {
                AppAnalysis.endLogPageView(name: $0)
                logger.trace("\($0) viewWillDisappear")
            }
        )
        Base.register(viewControllerDeinitAction: {
            logger.debug("\($0) deinit")
        })
    }
}
